package org.jeecg.modules.online.cgreport.service.impl;

import java.util.*;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONObject;
import org.jeecg.modules.online.cgreport.entity.DiagramConfiguration;
import org.jeecg.modules.online.cgreport.entity.DiagramFieldConfiguration;
import org.jeecg.modules.online.cgreport.mapper.DiagramConfigurationMapper;
import org.jeecg.modules.online.cgreport.service.IDiagramConfigurationService;
import org.jeecg.modules.online.cgreport.service.impl.DiagramFieldConfigurationServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.StringUtils;

/**
 * @Description: 图表配置
 */
@Service
public class DiagramConfigurationServiceImpl extends ServiceImpl<DiagramConfigurationMapper, DiagramConfiguration>
		implements IDiagramConfigurationService {

	@Autowired
	private DiagramFieldConfigurationServiceImpl diagramFieldConfigurationService;
	@Resource
	private DiagramConfigurationMapper diagramConfigurationMapper;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void add(DiagramConfiguration diagramConfiguration) {
		// 保存主表信息
		this.save(diagramConfiguration);
		// 保存子表信息
		if (diagramConfiguration != null && diagramConfiguration.getDiagramFieldConfigurationList() != null
				&& !diagramConfiguration.getDiagramFieldConfigurationList().isEmpty()) {
			diagramConfiguration.getDiagramFieldConfigurationList()
					.forEach(dfc -> dfc.setDiagramCode(diagramConfiguration.getCode()));
			this.diagramFieldConfigurationService.saveBatch(diagramConfiguration.getDiagramFieldConfigurationList());
		}

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void edit(DiagramConfiguration diagramConfiguration) {
		this.updateById(diagramConfiguration);
		// 更新子表信息
		Map<String, Object> columnMap = new HashMap<>();
		columnMap.put("DIAGRAM_CODE", diagramConfiguration.getCode());
		this.diagramFieldConfigurationService.removeByMap(columnMap);
		this.diagramFieldConfigurationService.saveBatch(diagramConfiguration.getDiagramFieldConfigurationList());

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteById(String id) {
		DiagramConfiguration diagramConfiguration = super.getById(id);
		this.removeById(id);
		// 删除子表信息
		Map<String, Object> columnMap = new HashMap<>();
		columnMap.put("DIAGRAM_CODE", diagramConfiguration.getCode());
		this.diagramFieldConfigurationService.removeByMap(columnMap);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteBatch(String ids) {
		List<String> idList = Arrays.asList(ids.split(","));
		QueryWrapper<DiagramConfiguration> queryWrapper = new QueryWrapper<>();
		queryWrapper.in("ID", idList);
		List<DiagramConfiguration> diagramConfigurationList = super.list(queryWrapper);
		this.removeByIds(idList);
		// 删除子表信息
		if (diagramConfigurationList != null && !diagramConfigurationList.isEmpty()) {
			Map<String, Object> columnMap = new HashMap<>();
			for (DiagramConfiguration diagramConfiguration : diagramConfigurationList) {
				columnMap.clear();
				columnMap.put("DIAGRAM_CODE", diagramConfiguration.getCode());
				this.diagramFieldConfigurationService.removeByMap(columnMap);
			}
		}
	}

	@Override
	public List selectBySql(String sql) {
		return this.diagramConfigurationMapper.selectBySql(sql);
	}

	@Override
	public List<Map<String, Object>> handelTreeTableData(List<Map<String, Object>> dataList, String unfoldFieldName, String pid) {
		//根节点对象存放到这里
		List<Map<String, Object>> rootList = new ArrayList<>();
		//非最顶层根节点
		List<Map<String, Object>> bodyList = new ArrayList<>();

		for (Map<String, Object> data : dataList) {
			Map<String, Object> tempMap = data;

			// 处理属性排列顺序
			Map<String, Object> objMap = new LinkedHashMap<>();
			objMap.put("id", tempMap.get("id"));
			objMap.put(unfoldFieldName, tempMap.get(unfoldFieldName));
			objMap.put(pid, tempMap.get(pid));

			tempMap.remove(unfoldFieldName);
			tempMap.remove("id");
			tempMap.remove(pid);

			objMap.putAll(tempMap);

			if (objMap.get(pid).equals("0")) {
				rootList.add(objMap);
			} else {
				bodyList.add(objMap);
			}
		}

		return getTree(rootList, bodyList, pid);
	}

	private List<Map<String, Object>> getTree(List<Map<String, Object>> rootList, List<Map<String, Object>> bodyList, String pid) {
		if (bodyList.size() != 0){
			//声明一个map，用来过滤已操作过的数据
			Map<String,Object> map = new HashMap<>(bodyList.size());
			rootList.forEach(parent->getChild(parent,bodyList,map, pid));
			return rootList;
		}else{
			return rootList;
		}
	}

	private void getChild(Map<String, Object> parent, List<Map<String, Object>> bodyList, Map<String, Object> map, String pid) {
		List<Map<String, Object>> childList = new ArrayList<>();
		bodyList.stream().filter(c->!map.containsKey(c.get("id")))
				.filter(c->c.get(pid).equals(parent.get("id")))
				.forEach(c->{
					map.put(c.get("id").toString(), c.get(pid));
					getChild(c,bodyList,map, pid);
					childList.add(c);
				});
		if (childList.size() != 0) {
			parent.put("children", childList);
		}
	}

	@Override
	public String handelQuerySql(String cgrSql, JSONObject jsonO, List<DiagramFieldConfiguration> diagramFieldConfigurations) {
		List<String> fields = getFields(diagramFieldConfigurations);

		StringBuilder sbl = new StringBuilder();
		sbl.append("select * from (");
		sbl.append(cgrSql);
		sbl.append(") tt where 1 = 1");

		for (String key : jsonO.keySet()){
			if (!key.equals("templetCode") && fields.contains(key)) {
				JSONObject jsonObject = jsonO.getJSONObject(key);
				String queryMode = jsonObject.getString("queryType");
				if (queryMode.equals("group")) { // 范围查询
					String startValue = jsonObject.getString("startValue");
					String endValue = jsonObject.getString("endValue");
					if (!StringUtils.isEmpty(startValue) && !StringUtils.isEmpty(endValue)) {
						sbl.append(" and " + key + " >= '" + startValue + "' and " + key + " <= '" + endValue + "'");
					} else if (!StringUtils.isEmpty(startValue) && StringUtils.isEmpty(endValue)) {
						sbl.append(" and " + key + " >= '" + startValue + "'");
					} else if (StringUtils.isEmpty(startValue) && !StringUtils.isEmpty(endValue)) {
						sbl.append(" and " + key + " <= '" + endValue + "'");
					}
				} else if(queryMode.equals("more")){
					String val = jsonObject.getString("value");
					if (!StringUtils.isEmpty(val)) {
						String[] values = jsonObject.getString("value").split(",");
						sbl.append(" and " + key + " in (");

						for (int i=0; i< values.length; i++) {
							String value = values[i];
							if (i != values.length - 1) {
								sbl.append("'" + value + "',");
							} else {
								sbl.append("'" + value + "'");
							}
						}
						sbl.append(")");
					}
				} else { // 单值查询
					Object value = jsonObject.get("value");
					if (value instanceof Integer) {
						sbl.append(" and " + key + " = '" + value + "'");
					} else {
						sbl.append(" and " + key + " like '%" + value + "%'");
					}
				}
			}
		}

		return sbl.toString();
	}

	private static List<String> getFields(List<DiagramFieldConfiguration> diagramFieldConfigurations) {
		List<String> fields = new ArrayList<>();

		diagramFieldConfigurations.forEach(item -> {
			fields.add(item.getFieldName());
		});
		return fields;
	}
}
